#include "step.h"

#include <iostream>
#include <string>
#include <thread>

#include "interface.h"

// 统一的execute实现 - 所有Step共享
bool Step::execute(int &progress) {
  if (main_status_ == StepMainStatus::COMPLETED ||
      main_status_ == StepMainStatus::FAILED) {
    return false;
  }

  if (main_status_ == StepMainStatus::PENDING) {
    std::cout << "[" << notify_->getWorkflowName() << "-" << name_
              << "-开始执行]" << std::endl;
    main_status_ = StepMainStatus::RUNNING;
  }

  std::cout << "[" << notify_->getWorkflowName() << "-" << name_ << "-"
            << statusToString(current_status_) << "] 当前状态："
            << statusToString(current_status_) << std::endl;

  auto it = status_handlers_.find(current_status_);
  if (it == status_handlers_.end()) {
    main_status_ = StepMainStatus::FAILED;
    return false;
  }

  // 执行状态处理函数，获取下一个状态
  unsigned int next_status;
  bool success = it->second(next_status, progress);

  if (!success) {
    main_status_ = StepMainStatus::FAILED;
    current_status_ = getFailedStatus();
  } else {
    current_status_ = next_status;
    if (isCompleteStatus(current_status_)) {
      main_status_ = StepMainStatus::COMPLETED;
    }
  }

  return success;
}

bool InitStep::checkHardware(unsigned int &next_status, int &progress) {
  std::cout << "[" << notify_->getWorkflowName() << "-" << name_ << "-硬件检查]"
            << " 执行硬件自检..." << std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(1));
  progress = 20;

  // 30%失败概率
  if (std::rand() % 10 < 3) {
    std::cout << "[" << notify_->getWorkflowName() << "-" << name_
              << "-硬件检查]"
              << " 硬件自检失败" << std::endl;
    if (retry_count_ < 2) {
      retry_count_++;
      next_status = INIT_RETRY;
      return true;
    } else {
      notify_->onStepFailed(name_, "硬件自检多次失败");
      return false;
    }
  }
  next_status = INIT_LOAD_CONFIG;
  return true;
}

bool InitStep::loadConfig(unsigned int &next_status, int &progress) {
  std::cout << "[" << notify_->getWorkflowName() << "-" << name_ << "-加载配置]"
            << " 加载系统配置..." << std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(1));
  progress = 40;
  next_status = INIT_VALIDATE_PARAM;
  return true;
}

bool InitStep::validateParam(unsigned int &next_status, int &progress) {
  std::cout << "[" << notify_->getWorkflowName() << "-" << name_ << "-参数验证]"
            << " 验证参数有效性..." << std::endl;
  std::this_thread::sleep_for(std::chrono::seconds(1));
  progress = 100;
  next_status = INIT_COMPLETE;
  return true;
}

bool InitStep::retry(unsigned int &next_status, int &progress) {
  std::cout << "[" << notify_->getWorkflowName() << "-" << name_
            << "-初始化重试]"
            << " 重试硬件自检（第" << retry_count_ << "次）..." << std::endl;
  progress = 20;
  next_status = INIT_CHECK_HARDWARE;
  return true;
}

bool DataCollectionStep::prepareCollect(unsigned int &next_status,
                                        int &progress) {
  std::cout << "[" << notify_->getWorkflowName() << "-" << name_ << "-采集准备]"
            << " 开始准备采集..." << std::endl;
  progress = 10 + (collected_samples_ * 80) / total_samples_;

  try {
    support_->prepareForCollection();
    next_status = COLLECT_SAMPLE;
  } catch (const std::exception &e) {
    std::cout << "[" << notify_->getWorkflowName() << "-" << name_
              << "-采集准备]"
              << " 准备采集失败: " << e.what() << std::endl;
    if (prepare_retry_ < 2) {
      prepare_retry_++;
      next_status = COLLECT_RETRY_PREPARE;
    } else {
      notify_->onStepFailed(name_, "采集准备多次失败");
      return false;
    }
  }
  return true;
}

bool DataCollectionStep::collectSample(unsigned int &next_status,
                                       int &progress) {
  std::cout << "[" << notify_->getWorkflowName() << "-" << name_ << "-采集样本]"
            << " 采集第" << (collected_samples_ + 1) << "个样本..."
            << std::endl;
  progress = 20 + (collected_samples_ * 80) / total_samples_;
  std::this_thread::sleep_for(std::chrono::seconds(1));

  // 20%失败概率
  if (std::rand() % 10 < 2) {
    std::cout << "[" << notify_->getWorkflowName() << "-" << name_
              << "-采集样本]"
              << " 样本采集失败" << std::endl;
    if (collect_retry_ < 2) {
      collect_retry_++;
      next_status = COLLECT_RETRY_SAMPLE;
      return true;
    } else {
      notify_->onStepFailed(name_, "样本采集多次失败");
      return false;
    }
  }

  collected_samples_++;
  next_status = COLLECT_VERIFY;
  return true;
}

bool DataCollectionStep::verifyData(unsigned int &next_status, int &progress) {
  std::cout << "[" << notify_->getWorkflowName() << "-" << name_ << "-数据验证]"
            << " 验证样本有效性..." << std::endl;
  std::this_thread::sleep_for(std::chrono::milliseconds(500));
  progress = 30 + (collected_samples_ * 70) / total_samples_;

  if (collected_samples_ >= total_samples_) {
    next_status = COLLECT_COMPLETE;
  } else {
    next_status = COLLECT_PREPARE;
  }
  return true;
}

bool DataCollectionStep::retryPrepare(unsigned int &next_status,
                                      int &progress) {
  std::cout << "[" << notify_->getWorkflowName() << "-" << name_ << "-准备重试]"
            << " 重试采集准备（第" << prepare_retry_ << "次）..." << std::endl;
  progress = 10 + (collected_samples_ * 80) / total_samples_;
  next_status = COLLECT_PREPARE;
  return true;
}

bool DataCollectionStep::retryCollect(unsigned int &next_status,
                                      int &progress) {
  std::cout << "[" << notify_->getWorkflowName() << "-" << name_ << "-采集重试]"
            << " 重试样本采集（第" << collect_retry_ << "次）..." << std::endl;
  progress = 20 + (collected_samples_ * 80) / total_samples_;
  next_status = COLLECT_SAMPLE;
  return true;
}